/*
 * @ObjectFactory.java	2008/07/28
 *
 * Copyright 2008 Web & Zen Multimedia, All rights reserved.
 * Use is subject to license terms.
 */
package it.wzm.lightweightlog;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

/**
 * ObjectFactory is the accessor for getting all instances of Queue, QueueDumper and Register. Because only one instance of each must exists
 * @author Leonardo Celati
 */
final class ObjectFactory implements Constant{
    
    /**
     * The Queue holder
     */
    private static Queue<? extends Entry> q;
    /**
     * The Register holder
     */
    private static Register<? extends Dumper> r;
    /**
     * The QueueDumper holder
     */
    private static QueueDumper qd;
    
    
    /**
     * This method will return an instance only of Queue depending
     * on which implementation we required
     * @param className example it.wzm.common.lightweight.object.FastQueue
     * @return an instance of Queue
     */
    @SuppressWarnings("unchecked")
    static Queue<? extends Entry> initQueue(Properties p) {
    	Log.serviceLog(p);
        // we first check if we already have a
        // queue available, if not we instantiate
        // and store it in variable 'q'
        if (q==null) {
            try {
                // get default if className is null
                // find the default in Constant interface
            	String className;
                if (p.containsKey("classname")) {
                	className = (String)p.get("classname");
                } else {
                    className = DEFAULT_QUEUE;
                }

                // deciding which instance of Queue we want to create
                Class<?> c = Class.forName(className);
                Constructor<?> cst = c.getConstructor(Properties.class);
                q = (Queue<? extends Entry>) cst.newInstance(new Object[] {p});
                                
            } catch (ClassNotFoundException e) {
                Log.serviceLog(e);
            } catch (NoSuchMethodException e) {
                Log.serviceLog(e);
            } catch (InstantiationException e) {
                Log.serviceLog(e);
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                Log.serviceLog(e);
            } catch (IllegalAccessException e) {
                Log.serviceLog(e);
            } catch (RuntimeException e) {
                Log.serviceLog(e);
            }
            
        }
        // finally we return q
        return q;
    }
    
    
    /**
     * Initialize our Register with a given implementation classname and a set of Dumper
     * @param className the name of the class
     * @param d Our array of Dumper
     * @return A valid Register
     */
    @SuppressWarnings("unchecked")
    static Register<? extends Dumper> initRegister(Properties p, Dumper... d) {
        Log.serviceLog(p);
        if (r == null)  {
            // if classname is null we try with the default implementation
        	String className;
            if (p.containsKey("classname")) {
            	className = (String)p.get("classname");
            } else {
                className = DEFAULT_REGISTER;
            }
            // then...all that follows to get a valid Register
            try {
                // deciding which instance of Register we want to create
                Class<?> c = Class.forName(className);
                Constructor<?> cst = c.getConstructor(Properties.class,Dumper[].class);
                r = (Register<? extends Dumper>) cst.newInstance(new Object[] {p,d});
                
            } catch (ClassNotFoundException e) {
                Log.serviceLog(e);
            } catch (NoSuchMethodException e) {
                Log.serviceLog(e);
            } catch (InstantiationException e) {
                Log.serviceLog(e);
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                Log.serviceLog(e);
            } catch (IllegalAccessException e) {
                Log.serviceLog(e);
            } catch (RuntimeException e) {
                Log.serviceLog(e);
            }
            
        }
        // returning our register
        return r;
    }
        
    /**
     * Initialize our QueueDumper
     * @return A valid QueueDumper
     */
    static QueueDumper initQueueDumper(Properties p) {
    	Log.serviceLog(p);
        if (qd == null) {
            qd = new QueueDumper(p);
        }
        return qd;
    }
    
    /**
     * Getter for Queue
     * @return Queue
     */
    static Queue<? extends Entry> getQueue() {
        return q;
    }
    
    /**
     * Getter for Register
     * @return Register
     */
    static Register<? extends Dumper> getRegister() {
        return r;
    }
    
    /**
     * Getter for QueueDumper
     * @return QueueDumper
     */
    static QueueDumper getQd() {
        return qd;
    }
    
}

